package com.richrail.model.entities;

import java.util.ArrayList;
import java.util.List;

import com.richrail.state.TrainState;
import com.richrail.state.WagonState;

public class Train implements Unit
{
	private String name;
	
	// This could also be a LinkedHashSet, but their is not really a need,
	// since we capture uniqueness within the add method.
	private List<Wagon> wagons = new ArrayList<Wagon>();
	
	public Train(String name)
	{
		this.name = name;
	}
	
	@Override
	public String getName()
	{
		return name;
	}
	
	public boolean addWagon(Wagon wagon)
	{
		return wagons.add(wagon);
	}
	
	public boolean removeWagon(Wagon wagon)
	{
		return wagons.remove(wagon);
	}
	
	public void clearWagons()
	{
		for (Wagon wagon: wagons)
		{
			wagon.decoupleFromTrain();
		}
		
		wagons.clear();
	}
	
	@Override
	public int getSeatCount()
	{
		int count = 0;
		
		for (Wagon wagon: wagons)
		{
			count += wagon.getSeatCount();
		}
		
		return count;
	}
	
	// We first had the state created at the getState method within the Depot,
	// but that way we needed to break the encapsulation (we made all Train and Wagon attributes accessible
	// through accessor methods), which would be bad design, since it breaks one of the OO core principles.
	public TrainState getState()
	{
		List<WagonState> wagonStates = new ArrayList<WagonState>();
		
		for (Wagon w: wagons)
		{
			wagonStates.add(w.getState());
		}
		
		return new TrainState(name, wagonStates);
	}
	
	// This could be moved to an abstract class, since it is the same for all units,
	// but the gains of not repeating yourself would not stand against the losses in flexibility.
	@Override
	public boolean equals(Object o)
	{
		if (o instanceof Train)
		{
			return ((Train) o).name.equals(name);
		}
		
		return false;
	}
	
	@Override
	public String toString()
	{
		return name;
	}
}
